package com.irany.component;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import com.irany.App;
import com.irany.enums.TaskStatusEnum;
import com.irany.enums.TaskTypeEnum;
import com.irany.model.MyReportInfo;
import com.irany.model.MyReportResult;
import com.irany.util.SeleniumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xslf.usermodel.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.awt.*;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 我报告的
 *
 * @author shujian.ou
 * @since 2021/5/17 0017 15:57
 */
public class MyReportCollector extends AbstractCollector {

    private final SimpleDateFormat chineseDateFormat = DateUtil.newSimpleFormat("yyyy-MM-dd KK:mm aa");

    public MyReportCollector(App app) {
        super(app);
    }

    private Set<MyReportInfo> record(boolean todo) {
        WebDriver driver = getDriver();
        List<WebElement> taskList = driver.findElements(By.cssSelector("#mainForm table > tbody > tr"));
        Set<MyReportInfo> infos = new HashSet<>(taskList.size());

        for (WebElement t : taskList) {
            WebElement jiraKeywordElement = t.findElement(By.cssSelector(todo ? "td:nth-child(1) > a" : "td:nth-child(1) > a"));

            TaskTypeEnum taskType = TaskTypeEnum.getByName(t.findElement(By.xpath("td[8]")).getText());
            if (taskType == null) {
                taskType = TaskTypeEnum.getByName(t.findElement(By.xpath("td[10]")).getText());
            }

            infos.add(
                    MyReportInfo.builder()
                            .keyword(jiraKeywordElement.getText())
                            .url(jiraKeywordElement.getAttribute("href"))
                            .title(t.findElement(By.cssSelector(todo ? "td:nth-child(3)" : "td:nth-child(2)")).getText())
                            .status(t.findElement(By.cssSelector(todo ? "td:nth-child(4)" : "td:nth-child(3)")).getText())
                            .solutionResult(t.findElement(By.cssSelector("td:nth-child(4)")).getText())
                            .solutionEndTime(t.findElement(By.cssSelector("td:nth-child(5)")).getText())
                            .createTime(t.findElement(By.cssSelector(todo ? "td:nth-child(5)" : "td:nth-child(6)")).getText())
                            .updateTime(t.findElement(By.cssSelector("td:nth-child(7)")).getText())
                            .type(taskType)
                            .build()
            );
        }

        boolean nextPageExist = SeleniumUtils.existElement(driver, By.cssSelector("#nextpage"));

        if (nextPageExist) {
            driver.findElement(By.cssSelector("#nextpage")).click();
            infos.addAll(record(todo));
        }
        return infos;
    }

    private void buildPpt(MyReportResult reportResult) throws Exception {
        Set<MyReportInfo> reportInfos = reportResult.getInfos();
        Date now = new Date();


        InputStream is = new FileInputStream(FileUtil.file("ppt_template.pptx"));
        XMLSlideShow ppt = new XMLSlideShow(is);
        List<XSLFSlide> slides = ppt.getSlides();
        for (XSLFSlide slide : slides) {
            List<XSLFShape> shapes = slide.getShapes();
            for (XSLFShape shape : shapes) {
                if (shape != null) {
                    if (shape instanceof XSLFTextBox) {
                        //填充首页信息
                        fillHomePage(shape);
                    }

                    if (shape instanceof XSLFTable) {
                        if ("本周上线情况".equals(((XSLFTextBox) shapes.get(1)).getText())) {
                            fillThisWeekTask(reportInfos, shape);
                        }

                        /*if ("下周工作计划".equals(((XSLFTextBox) shapes.get(1)).getText())) {

                        }*/
                    }
                }
            }
        }
        BufferedOutputStream out = null;
        try {
            FileWriter fileReader = FileWriter.create(new File(String.format("互动课件周报-%s-M%sW%s.pptx", getApp().getUserInfo().getFullName(), DateUtil.month(now) + 1, DateUtil.weekOfMonth(now))));
            out = fileReader.getOutputStream();
            ppt.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

    /**
     * 填充首页信息
     */
    private void fillHomePage(XSLFShape shape) {
        XSLFTextBox textBox = (XSLFTextBox) shape;
        String text = textBox.getText();
        switch (text) {
            case "${title}":
                XSLFTextRun textRun = textBox.setText("互动课件周报");
                textRun.setBold(true);
                textRun.setFontColor(Color.BLACK);
                textRun.setFontSize(48D);
                textRun.setFontFamily("微软雅黑");
                break;
            case "${date}":
                textRun = textBox.setText(DateUtil.today());
                textRun.setFontColor(Color.BLACK);
                textRun.setFontSize(24D);
                textRun.setFontFamily("微软雅黑");
                break;
            case "${reporter}":
                textRun = textBox.setText("少儿事业部-技术组-欧书剑");
                textRun.setBold(true);
                textRun.setFontColor(Color.RED);
                textRun.setFontSize(24D);
                textRun.setFontFamily("微软雅黑");
                break;
            default:
                break;
        }
    }

    /**
     * PPT填充本周任务情况
     */
    private void fillThisWeekTask(Set<MyReportInfo> reportInfos, XSLFShape shape) throws ParseException {
        XSLFTable table = (XSLFTable) shape;
        List<XSLFTableRow> rows = table.getRows();
        //筛选出没有记录的状态 & 过滤已否决的任务
        List<MyReportInfo> reportInfoList = reportInfos.stream().filter(r -> TaskStatusEnum.getByName(r.getStatus()) == null || !TaskStatusEnum.REJECTED.getName().equals(r.getStatus())).collect(Collectors.toList());
        int reportSize = reportInfoList.size();

        for (int i = 0; i < reportSize - 1; i++) {
            table.addRow();
        }

        for (int i = 1; i < reportSize + 1; i++) {
            List<XSLFTableCell> cells = rows.get(i).getCells();
            if (StringUtils.isNotBlank(cells.get(0).getText())) {
                //行头跳过
                continue;
            }

            MyReportInfo report = reportInfoList.get(i - 1);
            if (TaskTypeEnum.TASK.equals(report.getType())) {
                cells.get(0).setText("技术需求").setFontSize(10D);
            } else if (TaskTypeEnum.STORY.equals(report.getType())) {
                cells.get(0).setText("产品需求").setFontSize(10D);
            } else if (TaskTypeEnum.BUG.equals(report.getType())) {
                cells.get(0).setText("BUG/缺陷").setFontSize(10D);
            } else if (report.getType() != null) {
                cells.get(0).setText(StringUtils.join(report.getType().getTypeName(), "/")).setFontSize(10D);
            }


            //JIRA编号
            XSLFTextRun jiraNoRun = cells.get(1).setText(report.getKeyword());
            jiraNoRun.setFontSize(10D);
            jiraNoRun.createHyperlink().setAddress(report.getUrl());
            if (report.getSolutionEndTime() != null) {
                //问题解决时间不为空时才计算耗时和DDL
                Date createTime = chineseDateFormat.parse(report.getCreateTime());
                Date solutionEndTime = chineseDateFormat.parse(report.getSolutionEndTime());
                long dateBetween = DateUtil.between(createTime, solutionEndTime, DateUnit.DAY);
                if (dateBetween == 0L) {
                    dateBetween = 1L;
                }
                //耗时
                cells.get(2).setText(dateBetween + "d").setFontSize(10D);
                //DDL
                cells.get(3).setText(DateUtil.format(solutionEndTime, DatePattern.NORM_DATE_PATTERN)).setFontSize(10D);
            }
            //概要
            cells.get(5).setText(report.getTitle() + (TaskStatusEnum.COMPLETE.getName().equals(report.getStatus()) ? "    " + TaskStatusEnum.COMPLETE.getName() : "")).setFontSize(10D);
        }
    }


    @Override
    public void run() {
        try {
            getDriver().manage().window().maximize();
            Date now = new Date();
            //周一
            String beginWeekDate = DateUtil.beginOfWeek(now).toDateStr();
            //周六
            String endWeekDate = DateUtil.offsetDay(DateUtil.parse(beginWeekDate), 5).toDateStr();


            MyReportResult reportResult = new MyReportResult();

            //我报告的
            SeleniumUtils.openNewWindowAndSwitch(getDriver(), String.format("http://jira.zmops.cc/secure/myDeskAction!mainpage.jspa?tabId=2&queryType=&orderName=KEY&desc=true&begintime=%s&endtime=%s&beginclosedtime=&endclosedtime=&issueTypeId=&resultioned=&pageSize=100&currentPage=1", beginWeekDate, endWeekDate));
            Set<MyReportInfo> reports = record(false);
            close();

            //我的待办
            SeleniumUtils.openNewWindowAndSwitch(getDriver(), String.format("http://jira.zmops.cc/secure/myDeskAction!mainpage.jspa?tabId=2&queryType=&orderName=KEY&desc=true&begintime=%s&endtime=%s&beginclosedtime=&endclosedtime=&issueTypeId=&resultioned=&pageSize=100&currentPage=1", beginWeekDate, endWeekDate));
            reports.addAll(record(true));
            close();

            //我经办的
            SeleniumUtils.openNewWindowAndSwitch(getDriver(), String.format("http://jira.zmops.cc/secure/myDeskAction!mainpage.jspa?tabId=5&queryType=&orderName=KEY&desc=true&begintime=%s&endtime=%s&beginclosedtime=&endclosedtime=&issueTypeId=&resultioned=&pageSize=100&currentPage=1", beginWeekDate, endWeekDate));
            reports.addAll(record(false));
            close();

            reportResult.setInfos(reports);
            buildPpt(reportResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
